home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
combi113.zip
/
COMBI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-03
|
12KB
|
390 lines
/*
* This program is copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.
*
* The source is supplied as an example of interface to COMBI-disk (C)
* device driver. You may change the source as You wish, however I'm not
* responsible for the results of Your changes.
*
* Exit status:
* 3 - COMBI-disk not found;
* 2 - incorrect usage;
* 1 - can't change options or reallocate buffer;
* 0 - O'K - no errors.
*
* The program is written for MS C 6.0 and may be compiled in TINY or
* SMALL memory model.
*
* I apologize if the code looks cumbersome but I tried to make it most
* compatible with other compilers. (Turbo C 2.0 compiles it O'K).
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <ctype.h>
#include "ioctl.h" /* definitions of structures and control codes */
/* ANSI escape sequences to control colour output. If ANSI is not detected
* all they are changed to point to an empty string. */
char *A_bold = "\x1b[1m";
char *A_red = "\x1b[1;31m";
char *A_yell = "\x1b[1;33m";
char *A_cyan = "\x1b[1;36m";
char *A_norm = "\x1b[0m";
char drive=2;
static void
show_status(struct combi_status *cmb_st)
{
char opt;
printf("\t%sCOMBI-disk version %1d.%02d installed as drive %c:%s\n",
A_yell,
cmb_st->version >> 8, cmb_st->version & 0xff, drive+'A'-1, A_norm);
printf("\n\t%sCurrent status:%s\n", A_bold, A_norm);
printf("buffer size: %s%5dK%s\n", A_cyan, cmb_st -> buff_size, A_norm);
printf("current size: %s%5dK%s\n", A_cyan, cmb_st -> curr_size, A_norm);
printf("total number of blocks: %s%4d%s (%s%d%s sectors each)\n",
A_cyan, cmb_st -> n_blocks, A_norm,
A_cyan, cmb_st -> bl_sect, A_norm);
printf("current number of blocks: %s%4d%s (%s%d%s - RAM disk, %s%d%s - cache)\n",
A_cyan, cmb_st -> n_curr, A_norm,
A_cyan, cmb_st -> n_bl_RD, A_norm,
A_cyan, cmb_st -> n_bl_Cache, A_norm);
opt = cmb_st -> COMBI_options;
if(opt & OPT_WR_ON) { /* only if write caching is on */
printf("dirty blocks: %s%d%s, errors: %s%d%s\n",
A_cyan, cmb_st -> n_dirty, A_norm,
A_cyan, cmb_st -> n_errors, A_norm);
};
printf("\n\t%sOptions in order:%s\n", A_bold, A_norm);
if(!(opt & OPT_OFF)) {
printf("cache is %son%s (%s),\n", A_cyan, A_norm,
(opt & OPT_FREEZE) ? "frozen" : "not frozen");
printf("write caching is %s%s%s,\n", A_cyan,
(opt & OPT_WR_ON) ? "on" : "off", A_norm);
if(opt & OPT_WR_ON) {
printf("delayed write is %s%s%s,\n", A_cyan,
(opt & OPT_DW_OFF) ? "off" : "on", A_norm);
};
} else {
printf("cache is %soff%s,\n", A_cyan, A_norm);
};
printf("memory allocation is %s%s%s.\n", A_cyan,
(opt & OPT_MEM) ? "fixed" : "not fixed", A_norm);
printf("\n\t%sStatistics:%s\n", A_bold, A_norm);
printf("RAM disk reads: %s% 6u/%-6u%s\n",
A_cyan, cmb_st -> read_RD_num, cmb_st -> read_RD_sect, A_norm);
printf("RAM disk writes:%s% 6u/%-6u%s\n", A_cyan,
cmb_st -> write_RD_num, cmb_st -> write_RD_sect, A_norm);
if(!(opt & OPT_OFF)){
printf("Hard disk reads - requested: %s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
A_cyan, cmb_st -> read_rq, cmb_st -> read_sect, A_norm,
A_cyan, cmb_st -> read_rq_a, cmb_st -> read_sect_a, A_norm);
printf("Hard disk writes - requested:%s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
A_cyan, cmb_st -> write_rq, cmb_st -> write_sect, A_norm,
A_cyan, cmb_st -> write_rq_a, cmb_st -> write_sect_a, A_norm);
}
}
static int
change_mem(char drive, int ver, int memch)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
if(memch > 0) {
ctl[2] = CMD_EXPAND; /* command code for COMBI-disk - expand memory */
*(int *)&ctl[3] = memch;/* the amount of Kbytes to change memory size */
} else {
ctl[2] = CMD_SHRINK; /* command code for COMBI-disk - shrink memory */
*(int *)&ctl[3] = - memch;
}
r.x.ax=0x4405; /* DOS function: 'write IOCtl to block device' */
r.h.bl=drive; /* device number */
r.x.dx=(unsigned)&ctl; /* address of IOCtl packet */
r.x.cx=5; /* IOCtl packet length */
intdos(&r,&r);
if(r.x.cflag & 01) /* test for error return code */
return -1;
else
return 0;
}
static int
change_opt(char drive, int ver, char opt)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
ctl[2] = CMD_CH_OPT; /* command to COMBI-disk - change options */
ctl[3] = opt; /* the byte with new options follows the command */
r.x.ax=0x4405;
r.h.bl=drive;
r.x.dx=(unsigned)&ctl;
r.x.cx=4;
intdos(&r,&r);
if(r.x.cflag & 01)
return -1;
else
return 0;
}
static int
reset_counters(char drive, int ver)
{
unsigned char ctl[12];
union REGS r;
*(int *)&ctl = ver;
ctl[2] = CMD_RESET_C; /* command to COMBI-disk - reset counters */
ctl[3] = 7; /* reset all three types of counters */
r.x.ax=0x4405;
r.h.bl=drive;
r.x.dx=(unsigned)&ctl;
r.x.cx=4;
intdos(&r,&r);
if(r.x.cflag & 01)
return -1;
else
return 0;
}
static void
usage(void)
{
printf("\t%sCOMBI-disk (C) control program.%s\n"
"Copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.\n",
A_yell, A_norm);
printf("Usage: %sCOMBI [[+|-]#] [<option>[+|-]]...%s\n",
"where:\n", A_bold, A_norm);
printf(" %s# (number)%s - expand or shrink memory used by COMBI-disk,\n",
A_bold, A_norm);
printf(" %sn%s - don't return 'sector not found' error,\n",
A_bold, A_norm);
printf(" %so%s - turn cache on ('%so-%s' - turn off),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sb%s - turn write caching on ('%sb-%s' - off),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %si%s - start writing immediately ('%si-%s' - delayed writing),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sf%s - fix memory settings ('%sf-%s' - release),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sz%s - freeze cache ('%sz-%s' - un-freese),\n",
A_bold, A_norm, A_bold, A_norm);
printf(" %sr%s - reset all counters.\n",
A_bold, A_norm);
exit(2);
}
static void
chk_ansi(void)
{
union REGS r;
r.x.ax = 0x4400; /* DOS IOCtl - get handle info */
r.x.bx = 0x0001; /* stdout handle */
intdos(&r,&r);
if((r.x.dx & 0x82) == 0x82) {
r.x.ax = 0x1a00;
int86(0x2f, &r, &r);
if(r.h.al == 0xff)
return;
}
/* Else output is redirected into file or ANSI is not installed.
* So, we should turn off escape sequences. */
A_bold = A_yell = A_red = A_cyan = A_norm = "";
}
main(int argc, char *argv[])
{
struct combi_status cmb_st;
union REGS r;
int i,j;
int exitstat=0;
char *chpt, optchar;
char oldopt, opt;
chk_ansi(); /* Determine whether ANSI driver is installed and whether
* the output is redirected to file */
/*
* Scan all drives and try to read IOCtl packet of length sizeof(cmb_st).
* If successful then probably that drive is COMBI's RAM disk. To ensure
* this we check that first 6 bytes of returned packet are "COMBI\0".
*/
do {
drive++;
r.x.ax=0x4404;
r.h.bl=drive;
r.x.cx=sizeof(cmb_st);
r.x.dx=(unsigned)&cmb_st;
} while (((intdos(&r,&r)!=sizeof(cmb_st))||
(r.x.cflag & 0x1)||
strcmp(cmb_st.ID_name,"COMBI"))&&(drive < 16));
if(drive >= 16) {
printf("%sError: COMBI-disk not installed!(?)%s\n", A_red, A_norm);
exit(3);
}
if(argc > 1) { /* any parameters? */
optchar = '\0';
oldopt = opt = cmb_st.COMBI_options;
for(i=1; i < argc; i++) { /* Scan all command line arguments. */
strlwr(argv[i]);
if(isdigit(*argv[i]) || *argv[i]=='-' || *argv[i]=='+') {
/* If an